package com.mojo.concurrent.concurrent_04_cas_atomic;

import sun.misc.Unsafe;

import java.util.concurrent.atomic.*;

/**
 * 原子类
 * <p>
 * * AtomicInteger主要方法：
 * * addAndGet(Integer delta)：原子新增并返回结果
 * * compareAndSet(Integer expect,Integer update):比较期望值并设置值
 * * getAndSet(Integer newValue):原子设置新值并返回旧值
 * * <p>
 * * AtomicIntegerArray主要方法
 * *  addAndGet(int i,Integer delta)：原子新增并返回结果
 * *  compareAndSet(int i,Integer expect,Integer update):比较期望值并设置值
 * *  getAndSet(int i,Integer newValue):原子设置新值并返回旧值
 * <p>
 * AtomicReference,原子更新多个变量，主要方法：
 *
 * @author <a href="mailto:sjj@jianzhimao.com">mojo</a>
 * copyright (C), 2013-2023, 广州九尾信息科技有限公司
 * @date 2023/2/17 9:32
 */
public class AtomicDemo01 {
    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger();
        int i = atomicInteger.addAndGet(1);
        System.out.println(i);
        boolean b = atomicInteger.compareAndSet(1, 4);
        System.out.println(b);
        int oldValue = atomicInteger.getAndSet(3);
        System.out.println(oldValue);
        System.out.println("=============================================");
        int[] intArr = new int[]{1, 3, 5};
        AtomicIntegerArray integerArray = new AtomicIntegerArray(intArr);
        int i1 = integerArray.addAndGet(1, 3);
        System.out.println(i1);
        // AtomicIntegerArray复制intArr,修改integerArray数组元素不会影响integerArray
        System.out.println(intArr[1]);
        System.out.println("=============================================");
        AtomicReference<User> atomicReference = new AtomicReference<>();

        System.out.println("=============================================");
        // 原子更新引用字段类型里的字段
        AtomicReferenceFieldUpdater<User, Integer> old = AtomicReferenceFieldUpdater.newUpdater(User.class, Integer.class, "old");
        User mojo = new User("mojo", 11);
        System.out.println(old.getAndSet(mojo, 22));
        System.out.println(old.get(mojo));
    }

    static class User {
        private String name;
        public volatile Integer old;

        public User(String name, int old) {
            this.name = name;
            this.old = old;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getOld() {
            return old;
        }

        public void setOld(int old) {
            this.old = old;
        }
    }
}
